<!DOCTYPE html>
<html>
<head>
    <title>Physics Diagram</title>
</head>
<body>
<canvas id="physicsCanvas" width="500" height="400"></canvas>

<script>
    const canvas = document.getElementById('physicsCanvas');
    const ctx = canvas.getContext('2d');

    // Style settings
    ctx.lineWidth = 2;
    ctx.strokeStyle = 'black';
    ctx.fillStyle = 'black';
    ctx.font = 'italic 22px Times New Roman';

    // Parameters
    const cx = canvas.width / 2;
    const R = 100;
    const cy = 150;
    const containerThickness = 30;
    const baseHeight = 20;
    const groundY = cy + R + baseHeight;
    const ballRadius = 8;

    // Function to draw an arrowhead
    function drawArrowhead(ctx, fromX, fromY, toX, toY, headLength = 10) {
        const angle = Math.atan2(toY - fromY, toX - fromX);
        ctx.save();
        ctx.beginPath();
        ctx.translate(toX, toY);
        ctx.rotate(angle);
        ctx.moveTo(0, 0);
        ctx.lineTo(-headLength, headLength / 2.5);
        ctx.moveTo(0, 0);
        ctx.lineTo(-headLength, -headLength / 2.5);
        ctx.stroke();
        ctx.restore();
    }

    // 1. Draw Ground
    ctx.beginPath();
    ctx.moveTo(0, groundY);
    ctx.lineTo(canvas.width, groundY);
    ctx.stroke();

    // Draw ground hatching
    ctx.lineWidth = 1.5;
    for (let i = 5; i < canvas.width + 20; i += 20) {
        ctx.beginPath();
        ctx.moveTo(i, groundY);
        ctx.lineTo(i - 15, groundY + 15);
        ctx.stroke();
    }
    ctx.lineWidth = 2; // Reset line width

    // 2. Define Container Path
    ctx.beginPath();
    ctx.moveTo(cx + R, cy);
    ctx.arc(cx, cy, R, 0, Math.PI, false); // Inner arc from right to left
    // path is now at (cx - R, cy)
    ctx.lineTo(cx - R - containerThickness, cy);
    ctx.lineTo(cx - R - containerThickness, groundY);
    ctx.lineTo(cx + R + containerThickness, groundY);
    ctx.lineTo(cx + R + containerThickness, cy);
    ctx.closePath(); // Connects back to (cx + R, cy)

    // 3. Fill container with hatching
    ctx.save();
    ctx.clip(); // Clip to the container shape
    ctx.lineWidth = 1.5;
    ctx.strokeStyle = '#222';
    // Draw long diagonal lines that are guaranteed to cover the clipped area
    for (let i = 0; i < canvas.width + canvas.height; i += 10) {
        ctx.beginPath();
        ctx.moveTo(i, 0);
        ctx.lineTo(i - canvas.height, canvas.height); // Lines with slope -1
        ctx.stroke();
    }
    ctx.restore(); // Remove clipping

    // 4. Stroke the container outline for a clean border
    ctx.lineWidth = 2;
    ctx.strokeStyle = 'black';
    ctx.stroke(); // Stroke the path defined in step 2

    // 5. Draw Ball and its label 'm'
    const ballX_A = cx + R;
    const ballY_A = cy;
    ctx.beginPath();
    ctx.arc(ballX_A, ballY_A, ballRadius, 0, 2 * Math.PI);
    ctx.fill();
    ctx.fillText('m', ballX_A - 35, ballY_A + 5);

    // 6. Draw Labels (A, B, O) and points
    // Point A
    ctx.font = '22px Times New Roman';
    ctx.fillStyle = 'black';
    ctx.fillText('A', ballX_A + 12, ballY_A + 8);

    // Point B
    const B_x = cx;
    const B_y = cy + R;
    ctx.beginPath();
    ctx.arc(B_x, B_y, 3.5, 0, 2 * Math.PI);
    ctx.fill();
    ctx.fillText('B', B_x + 10, B_y + 8);

    // Point O
    ctx.font = 'italic 22px Times New Roman';
    ctx.fillText('O', cx - 35, cy - 5);

    // 7. Draw Arrows (R and motion)
    // R arrow and label
    const R_angle = 2.2; // Angle for the arrow endpoint on the curve (approx. 126 degrees)
    const R_arrow_end_x = cx + R * Math.cos(R_angle);
    const R_arrow_end_y = cy + R * Math.sin(R_angle);
    const R_arrow_start_x = cx - 15;
    const R_arrow_start_y = cy - 15;
    ctx.beginPath();
    ctx.moveTo(R_arrow_start_x, R_arrow_start_y);
    ctx.lineTo(R_arrow_end_x, R_arrow_end_y);
    ctx.stroke();
    drawArrowhead(ctx, R_arrow_start_x, R_arrow_start_y, R_arrow_end_x, R_arrow_end_y);
    ctx.fillText('R', R_arrow_start_x - 5, R_arrow_start_y - 10);

    // Motion arrow
    const motionArrowAngleStart = 0.15;
    const motionArrowAngleEnd = 0.55;
    ctx.beginPath();
    // Draw the arc slightly inside the path for clarity
    ctx.arc(cx, cy, R, motionArrowAngleStart, motionArrowAngleEnd);
    ctx.stroke();
    const arrowEndX = cx + R * Math.cos(motionArrowAngleEnd);
    const arrowEndY = cy + R * Math.sin(motionArrowAngleEnd);
    // Calculate a point on the tangent to orient the arrowhead correctly
    const tangentAngle = motionArrowAngleEnd + Math.PI / 2;
    const fromX = arrowEndX - 10 * Math.cos(tangentAngle);
    const fromY = arrowEndY - 10 * Math.sin(tangentAngle);
    drawArrowhead(ctx, fromX, fromY, arrowEndX, arrowEndY);

    // 8. Draw Text below diagram
    ctx.font = '24px "Songti SC", "SimSun"'; // Font for Chinese characters
    ctx.fillStyle = 'black';
    ctx.fillText('题 10 图', cx - 40, groundY + 60);

</script>
</body>
</html>